package com.example.downloaddemo.download;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.ThreadPoolExecutor;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;

import android.net.http.AndroidHttpClient;

public class DownloadTaskExcutor {
	private File mSaveFile;// The file for save
	private File mDescFile;// The file for description about the download
							// information

	private RandomAccessFile mRandomAccessSaveFile;
	private RandomAccessFile mRandomAccessDescFile;

	private ThreadPoolExecutor mExecutor;

	private DownloadStatusListener mDownloadListener;

	public DownloadStatusListener getDownloadListener() {
		return mDownloadListener;
	}

	public void setDownloadListener(DownloadStatusListener downloadListener) {
		mDownloadListener = downloadListener;
	}

	public DownloadTaskExcutor(File saveFile, File descFile)
			throws FileNotFoundException {
		mSaveFile = saveFile;
		mDescFile = descFile;
		mRandomAccessSaveFile = new RandomAccessFile(mSaveFile, "rw");
		mRandomAccessDescFile = new RandomAccessFile(mDescFile, "rw");
	}

	public void excute(final DownloadTask task) {
		if (mSaveFile == null) {
			mSaveFile = new File(task.getmSaveFile());
			if (mSaveFile.exists()) {
				if (mDownloadListener != null) {
					mDownloadListener.onFileExisted(task.getDownloadInfo());
				}
			}
		}
		if (mRandomAccessSaveFile == null) {
			try {
				mRandomAccessSaveFile = new RandomAccessFile(mSaveFile, "rw");
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
		Thread th = new Thread(new Runnable() {
			@Override
			public void run() {
				if (mDownloadListener != null) {
					mDownloadListener.onStart(task.getDownloadInfo());
				}
				AndroidHttpClient client = AndroidHttpClient.newInstance(null);
				String downloadUrl = task.getDownloadInfo().downloadUrl;
				HttpGet get = new HttpGet(downloadUrl);
				try {
					HttpResponse response = client.execute(get);
					final long contentLength = response.getEntity()
							.getContentLength();
					if (contentLength != task.getmContentLength()) {
						if (mDownloadListener != null) {
							mDownloadListener.onFailed(task.getDownloadInfo());
						}
					}
					byte[] buffer = new byte[DownloadConstants.DOWNLOAD_BUFFER_SIZE];
					BufferedInputStream bis = new BufferedInputStream(response
							.getEntity().getContent(),
							DownloadConstants.DOWNLOAD_BUFFER_SIZE);
					int readed = 0;
					long downloadedLength = task.getDownloadedLength();
					RandomAccessFile randomAccessFile = mRandomAccessDescFile;
					while ((readed = bis.read(buffer, 0,
							DownloadConstants.DOWNLOAD_BUFFER_SIZE)) > 0) {
						randomAccessFile.write(buffer, 0, readed);
						downloadedLength += readed;
						task.setDownloadedLength(downloadedLength);
						if (mDownloadListener != null) {
							mDownloadListener.onUpdateProgress(
									task.getDownloadInfo(),
									(int) (downloadedLength / contentLength));
						}
					}
					if (mDownloadListener != null) {
						mDownloadListener.onFinished(task.getDownloadInfo());
					}
				} catch (IOException e) {
					e.printStackTrace();
					if (mDownloadListener != null) {
						mDownloadListener.onFailed(task.getDownloadInfo());
					}
				}

			}
		});
		th.setPriority(Thread.MAX_PRIORITY);
		mExecutor.execute(th);
	}
}
